package com.fly.platform.common.exception

import com.fly.platform.common.utils.ResultUtil
import com.fly.platform.vo.FlyResult
import org.springframework.http.HttpStatus
import org.springframework.security.access.AccessDeniedException
import org.springframework.validation.BindException
import org.springframework.validation.FieldError
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestControllerAdvice
import java.util.function.Consumer

/**
 * @author fly
 */
@RestControllerAdvice
class RestCtrlExceptionHandler {

    @ExceptionHandler(FlyException::class)
    @ResponseStatus(value = HttpStatus.OK)
    fun handleFlyException(e: FlyException?): FlyResult<Any> {

        var errorMsg = "Fly exception: "
        e?.run {
            errorMsg = errorMsg.plus(e.message)
        }
        return ResultUtil.error(500, errorMsg)
    }

    @ExceptionHandler(BindException::class)
    @ResponseStatus(value = HttpStatus.OK)
    fun handleBindException(e: BindException): FlyResult<Any> {

        val sb = StringBuilder()
        e.fieldErrors.forEach(Consumer { error: FieldError ->
            val fieldName = error.field
            val message = error.defaultMessage
            sb.append("$fieldName-$message；")
        })
        var result = sb.toString()
        if (result.isNotEmpty()) {
            result = result.substring(0, result.length - 1)
        }
        return ResultUtil.error(500, result)
    }

    @ExceptionHandler(MethodArgumentNotValidException::class)
    @ResponseStatus(value = HttpStatus.OK)
    fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): FlyResult<Any> {

        val sb = StringBuilder()
        e.bindingResult.fieldErrors.forEach(Consumer { error: FieldError ->
            val fieldName = error.field
            val message = error.defaultMessage
            sb.append("$fieldName-$message；")
        })
        var result = sb.toString()
        if (result.isNotEmpty()) {
            result = result.substring(0, result.length - 1)
        }
        return ResultUtil.error(500, result)
    }

    @ExceptionHandler(AccessDeniedException::class)
    @ResponseStatus(value = HttpStatus.OK)
    fun handleAccessDeniedExceptionException(e: AccessDeniedException?): FlyResult<Any> {

        var errorMsg: String? = "AccessDeniedException exception"

        e?.run {
            errorMsg = errorMsg.plus(e.message)
        }
        return ResultUtil.error(500, errorMsg)
    }

    @ExceptionHandler(Exception::class)
    @ResponseStatus(value = HttpStatus.OK)
    fun handleException(e: Exception?): FlyResult<Any> {

        var errorMsg: String? = "Exception"
        e?.run {
            errorMsg = errorMsg.plus(e.message)
        }
        return ResultUtil.error(500, errorMsg)
    }
}